<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>自定义属性</title>
</head>
<body>
<script>

    /*
    * 这里的闭包将数据定义为外层函数的局部变量
    *
    * 使用闭包外部会无法访问到num
    * */
    function count1() {
        let num = 0

        return function () {
            console.log(++num)
        }
    }

    let foo = count1()
    foo()
    foo()


    /*
    * 函数是一种特殊的对象 我们不仅可以访问函数原生的对象和方法，也可以往函数身上动态添加属性
    * 这种方式外部可以访问到fn.身上的num 有点类似于面向对象
    *     * */
    function count2() {
        function fn() {
            console.log(++fn.num)
        }

        /*
        * 这里在预编译阶段就会创建fn
        * */
        fn.num = 0

        return fn
    }

    let foo1 = count2()
    foo1()
    foo1()

    console.log(foo1.num)


    /*
    * 我们不仅可以在函数式身上定义属性还可以定义函数
    * */

    function makeCount1() {
        let count = 0

        let increase = function () {
            console.log(++count)
        }

        let decrease = function () {
            console.log(--count)
        }

        /*
        * 之前函数内部如果想定义多个函数要么返回一个对象要么将函数定义在window身上
        * */
        return {
            increase,
            decrease
        }
    }

    // let {decrease,increase} =makeCount1()
    // decrease()
    // decrease()
    // increase()
    // increase()


    function makeCount2() {
        /*
        * 可以不用创建一个新的对象使用，使用已有的函数作为对象绑定属性
        * */
        function _makeCount() {
            console.log(_makeCount.count)
        }

        _makeCount.count = 0

        _makeCount.increase = function () {
            console.log(++count)
        }
        _makeCount.decrease = function () {
            console.log(--count)
        }

        return _makeCount
    }


    let {decrease, increase} = makeCount1()
    decrease()
    decrease()
    increase()
    increase()

    /*其实也可以把函数身上绑定属性和方法的操作转移到函数内部执行
    但是因为定义操作在函数体内部，所以只有函数调用的时候才能进行绑定操作

    在函数体外进行绑定的话不用调用函数就能操作前提是外部的代码在某个环节完成了执行
    *     function foo() {
        return function f() {
            f.age = 24
            f.getAge = function () {
                return f.age
            }
            f.setAge = function (age) {
                f.age = age
            }

        }
    }
    *
    *
    * */


</script>
</body>
</html>